package com.wolfsea.rvitemdecorationdemo.itemdecoration
import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.text.TextPaint
import android.util.Log
import android.view.View
import androidx.annotation.ColorRes
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.wolfsea.rvitemdecorationdemo.bean.Contact
import com.wolfsea.rvitemdecorationdemo.dp2px

/**
 *@desc  悬浮吸顶ItemDecoration
 *@author liuliheng
 *@time 2022/3/20  9:53
 **/
class SuspendItemDecoration(val context: Context) : RecyclerView.ItemDecoration() {

    var dividerDrawable: Drawable? = null
    var dividerGroupDrawable: Drawable? = null
    var contacts: List<Contact>? = null

    private val bounds = Rect()
    private val textPaint: TextPaint = TextPaint(TextPaint.ANTI_ALIAS_FLAG)

    @ColorRes
    var textColor: Int = android.R.color.white
        set(value) {
            field = value
            textPaint.color = context.resources.getColor(value)
        }
    var textSize: Float = 20F
        set(value) {
            field = value
            textPaint.textSize = context.dp2px(value)
        }
    var textTypeFace: Typeface = Typeface.DEFAULT_BOLD
        set(value) {
            field = value
            textPaint.typeface = value
        }

    init {
        textPaint.color = context.resources.getColor(textColor)
        textPaint.textSize = context.dp2px(textSize)
        textPaint.typeface = textTypeFace
    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)

        outRect.set(0, 0, 0, 0)
        val list = contacts ?: return

        val position = (view.layoutParams as RecyclerView.LayoutParams).viewLayoutPosition
        val currentInitial = list[position].initial
        val lastInitial = if (position >= 1) list[position -1].initial else null

        val drawable = if (currentInitial == lastInitial) dividerDrawable else dividerGroupDrawable
        val height = drawable?.intrinsicHeight ?: 0
        outRect.set(0, height, 0, 0)
    }

    override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(canvas, parent, state)

        val list = contacts ?: return
        canvas.save()

        val left = parent.paddingLeft
        val right = parent.width - parent.paddingRight

        val itemCount = parent.childCount
        for (i in 0.until(itemCount)) {

            val view = parent.getChildAt(i)
            val position = (view.layoutParams as RecyclerView.LayoutParams).viewLayoutPosition
            val currentInitial = list[position].initial
            val lastInitial = if (position >= 1) list[position -1].initial else null

            var isDrawText = false
            parent.getDecoratedBoundsWithMargins(view, bounds)
            val drawable = if (currentInitial == lastInitial) {
                dividerDrawable
            } else {
                isDrawText = true
                dividerGroupDrawable
            }

            val top = bounds.top
            val bottom = top + (drawable?.intrinsicHeight ?: 0)
            drawable?.setBounds(left, top, right, bottom)
            drawable?.draw(canvas)

            if (isDrawText) {
                if (drawable != null) {
                    textPaint.getTextBounds(currentInitial, 0, currentInitial.length, bounds)
                    val textX = view.paddingLeft.toFloat()
                    val textY = (view.top - (drawable.intrinsicHeight - bounds.height()) / 2).toFloat()
                    canvas.drawText(currentInitial, textX, textY, textPaint)
                }
            }
        }

        canvas.restore()
    }

    override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(canvas, parent, state)

        val list = contacts ?: return
        val drawable = dividerGroupDrawable ?: return

        //只判断LinearLayoutManager的情形
        val layoutManager = parent.layoutManager as? LinearLayoutManager ?: return

        val position = layoutManager.findFirstVisibleItemPosition()
        if (position < 0 || position > list.size - 1) {

            return
        }

        val child = parent.findViewHolderForLayoutPosition(position)!!.itemView

        val currentInitial = list[position].initial
        val nextInitial = if (position + 1 < list.size) list[position + 1].initial else null

        parent.getDecoratedBoundsWithMargins(child, bounds)

        canvas.save()
        if (currentInitial != nextInitial) {
            //顶部移出
            if (child.top + child.height < drawable.intrinsicHeight) {
                canvas.translate(
                    0F,
                    (child.top - child.height - drawable.intrinsicHeight).toFloat()
                )
            }
        }

        val left = parent.paddingLeft
        val top = parent.paddingTop
        val right = parent.width - parent.paddingRight
        val bottom = parent.paddingTop + drawable.intrinsicHeight
        drawable.setBounds(left, top, right, bottom)
        drawable.draw(canvas)

        textPaint.getTextBounds(currentInitial, 0, currentInitial.length, bounds)
        val textX = child.paddingLeft.toFloat()
        val textY = (parent.paddingTop + drawable.intrinsicHeight - (drawable.intrinsicHeight - bounds.height()) / 2).toFloat()
        canvas.drawText(currentInitial, textX, textY, textPaint)

        canvas.restore()
    }

}